package com.cq.utils;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.StringUtils;

import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.TimeZone;

/**
 * <日期操作工类> 用于对日期格式转换，字符串转换日期格式的工具类
 */
public final class DateUtils {

    /**
     * yyyy-MM-dd
     */
    public static final String DATE_TIME_01 = "yyyy-MM-dd";
    /**
     * yyyyMMdd
     */
    public static final String DATE_TIME_02 = "yyyyMMdd";

    /**
     *
     */
    public static final String DATE_TIME_03 = "yyyy-MM-dd HH:mm:ss";

    /**
     * yyyyMMddHHmmss
     */
    public static final String DATE_TIME_04 = "yyyyMMddHHmmss";


    /**
     * yyyy年MM月dd日
     */
    public static final String DATE_TIME_05 = "yyyy年MM月dd日";

    /**
     * yyyy-MM-dd HH:00:00
     */
    public static final String DATE_TIME_06 = "yyyy-MM-dd HH:00:00";

    /**
     * yyyy-MM-dd HH:00:00
     */
    public static final String DATE_TIME_07 = "yyyy-MM-dd HH" + "h";
    /**
     * The Constant LOGGER.
     */
    private static final Logger LOGGER = LoggerFactory.getLogger(DateUtils.class);

    /**
     * 私有化该实例 防止被实例化 DateUtils.
     */
    private DateUtils() {
        throw new IllegalArgumentException("The utility class isn't instantiated!");
    }

    /**
     * 转换字符串为Date.
     *
     * @param dateStr 要转换的时间字符串
     * @param format  时间格式
     * @return Date 时间类型结果
     */
    public static Date parseString(String dateStr, String format) {
        if (StringUtils.isEmpty(dateStr)) {
            LOGGER.warn("invalid data,dateStr={}", dateStr);
            return null;
        }

        if (StringUtils.isEmpty(format)) {
            LOGGER.warn("invalid format,format={}", format);
            return null;
        }
        DateFormat df = new SimpleDateFormat(format);
        Date date = null;
        try {
            date = df.parse(dateStr);
            if (!dateStr.equals(df.format(date))) {
                date = null;
            }
        } catch (ParseException e) {
            LOGGER.error("fail to parse date", e);
        }
        return date;
    }

    /**
     * 将日期转换未指定类型的字符串.
     *
     * @param date   要转换的date
     * @param format 格式
     * @return 转换完成的字符串
     */
    public static String formatDate(Date date, String format) {
        if (null == date) {
            return "";
        }
        DateFormat df = new SimpleDateFormat(format);
        return df.format(date);
    }

    public static String formatDate(Calendar calendar, String format) {
        if (null == calendar) {
            return "";
        }
        DateFormat df = new SimpleDateFormat(format);
        return df.format(calendar);
    }

    public static String formatDate(Date date, String format, String timeZone) {
        if (null == date) {
            return "";
        }
        DateFormat df = new SimpleDateFormat(format);
        df.setTimeZone(TimeZone.getTimeZone(timeZone));
        return df.format(date);
    }

    /**
     * 计算两个日期的相差天数
     * 日期都只有年月日
     */
    public static int daysBetween(Date smdate, Date bdate) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(smdate);
        long time1 = cal.getTimeInMillis();
        cal.setTime(bdate);
        long time2 = cal.getTimeInMillis();
        long between_days = (time2 - time1) / (1000 * 3600 * 24);
        return Integer.parseInt(String.valueOf(between_days));
    }

    /**
     * 计算相差指定天数后的日期
     *
     * @param stdate 指定日期
     * @param days   指定天数
     * @return 返回 date 目标日期
     * @author caowei
     * @date 20180522
     * @since v1.0
     */
    public static Date dateBetween(Date stdate, Integer days) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(stdate);
        cal.add(Calendar.DATE, days);
        return cal.getTime();
    }


    /**
     * 获取月份的最后一天
     *
     * @param year  年份
     * @param month 月份
     * @return 返回 month last day
     * @author zhongyong
     * @date 20180530
     * @since v1.0
     */
    public static int getMonthLastDay(int year, int month) {
        Calendar a = Calendar.getInstance();
        a.set(Calendar.YEAR, year);
        a.set(Calendar.MONTH, month - 1);
        //把日期设置为当月第一天
        a.set(Calendar.DATE, 1);
        //日期回滚一天，也就是最后一天
        a.roll(Calendar.DATE, -1);
        int maxDate = a.get(Calendar.DATE);
        return maxDate;
    }

    /**
     * 日期加减操作
     *
     * @param date
     * @param field
     * @param value
     * @return
     */
    public static Date add(Date date, int field, int value) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        cal.add(field, value);
        return cal.getTime();
    }

    /**
     * 判断两个日期是否在同一天
     *
     * @param date1
     * @param date2
     * @return
     */
    public static boolean isSameDay(Date date1, Date date2) {
        Calendar ca1 = Calendar.getInstance();
        Calendar ca2 = Calendar.getInstance();
        ca1.setTime(date1);
        ca2.setTime(date2);
        if ((ca1.get(Calendar.DATE) != ca2.get(Calendar.DATE))
                && (ca1.get(Calendar.YEAR) == ca2.get(Calendar.YEAR))
                && (ca1.get(Calendar.MONTH) == ca2.get(Calendar.MONTH))) {
            return false;
        }
        return true;
    }

    /**
     * 判定时间是否在一段范围内
     *
     * @param
     * @throws ParseException
     */
    public static boolean belongCalendar(Date nowTime, Date beginTime, Date endTime) {
        Calendar date = Calendar.getInstance();
        date.setTime(nowTime);
        Calendar begin = Calendar.getInstance();
        begin.setTime(beginTime);
        Calendar end = Calendar.getInstance();
        end.setTime(endTime);
        if (date.after(begin) && date.before(end)) {
            return true;
        } else if (nowTime.compareTo(beginTime) == 0 || nowTime.compareTo(endTime) == 0) {
            return true;
        } else {
            return false;
        }
    }

    /**
     * 字符串日期转为Date
     *
     * @param ld
     * @throws ParseException
     */
    public static Date strFormatDate(String ld) throws ParseException {
        DateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        Date lendDate = format.parse(ld);
        return lendDate;
    }

    /**
     * 判定当前时间是否超过当天20时
     *
     * @param
     * @throws
     */
    public static String getTime(Date date) {

        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        int hour = calendar.get(Calendar.HOUR_OF_DAY);
        if (hour < 20) {
            calendar.add(Calendar.DAY_OF_MONTH, -1);
        }
        String time = DateUtils.formatDate(calendar.getTime(), DateUtils.DATE_TIME_01);

        return time;
    }

    /**
     * 获取当前整时 yyyy-MM-dd HH:00
     *
     * @param
     * @throws
     */
    public static String wholeTime() {
        Date date = new Date();
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        int year = calendar.get(Calendar.YEAR);
        int month = calendar.get(Calendar.MONTH) + 1;
        int day = calendar.get(Calendar.DAY_OF_MONTH);
        int hour = calendar.get(Calendar.HOUR_OF_DAY);
        String wholeTime = year + "-" + month + "-" + day + " " + hour + ":" + "00";
        return wholeTime;
    }

    /**
     * 获取当前10天前整时 yyyy-MM-dd HH:00
     *
     * @param
     * @throws
     */
    public static String wholeTimeTenAgo() {
        Date date = new Date();
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.add(Calendar.DATE, -10);
        int hour = calendar.get(Calendar.HOUR_OF_DAY);
        Date start = calendar.getTime();
        String wholeTimeTenAgo = DateUtils.formatDate(start, DATE_TIME_01) + " " + hour + ":00";
        return wholeTimeTenAgo;
    }

    public static String getCurrentDate(String format) {
        Date date = new Date();
        return formatDate(date, format);
    }

    /**
     * 获取当前1天前或2天前整时 yyyy-MM-dd 20:00:00
     *
     * @param
     * @throws
     */
    public static String getStartTime() {
        Date date = new Date();
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        int year = calendar.get(Calendar.YEAR);
        int month = calendar.get(Calendar.MONTH) + 1;
        int hour = calendar.get(Calendar.HOUR_OF_DAY);
        String startTime = null;
        int day = 0;
        if (hour < 20) {
            day = calendar.get(Calendar.DAY_OF_MONTH) - 2;
            startTime = year + "-" + month + "-" + day + " " + 20 + ":" + "00" + ":" + "00";
        } else {
            day = calendar.get(Calendar.DAY_OF_MONTH) - 1;
            startTime = year + "-" + month + "-" + day + " " + 20 + ":" + "00" + ":" + "00";
        }
        return startTime;
    }

    public static String getSEndTime() {
        Date date = new Date();
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        int year = calendar.get(Calendar.YEAR);
        int month = calendar.get(Calendar.MONTH) + 1;
        int hour = calendar.get(Calendar.HOUR_OF_DAY);
        String endTime = null;
        int day = 0;
        if (hour < 20) {
            day = calendar.get(Calendar.DAY_OF_MONTH) - 1;
            endTime = year + "-" + month + "-" + day + " " + 20 + ":" + "00" + ":" + "00";
        } else {
            day = calendar.get(Calendar.DAY_OF_MONTH);
            endTime = year + "-" + month + "-" + day + " " + 20 + ":" + "00" + ":" + "00";
        }
        return endTime;
    }

    /**
     * 获取 year.
     *
     * @return 返回 year
     * @author zhouqi
     * @date 20180926
     * @since v1.0
     */
    public static Integer getYear() {
        Calendar calendar = Calendar.getInstance();
        return calendar.get(Calendar.YEAR);
    }

    /**
     * 获取 month.
     *
     * @return 返回 month
     * @author zhouqi
     * @date 20180926
     * @since v1.0
     */
    public static Integer getMonth() {
        Calendar calendar = Calendar.getInstance();
        return calendar.get(Calendar.MONTH);
    }
}
